package com.autumn.sms.service.core.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.autumn.sms.SmsEventData;
import com.autumn.sms.service.SmsSendException;
import com.autumn.sms.service.consts.ServiceConsts.Platform;
import com.autumn.sms.service.utils.HttpUtil;
import com.autumn.sms.service.vo.PlatformTemplateValue;
import com.autumn.util.tuple.TupleThree;

/**
 * 聚合短信
 * 
 * @author 老码农
 *
 *         2018-01-12 18:07:30
 */
@Service(Platform.BEAN_NAME_JUHE)
public class JuheSmsServiceImpl extends AbstractSmsPlatformService {

	private final static Map<Integer, TupleThree<Boolean, Boolean, String>> ERROR_MAP = new HashMap<>();

	static {
		ERROR_MAP.put(205401, new TupleThree<>(false, false, "错误的手机号码"));
		ERROR_MAP.put(205402, new TupleThree<>(false, false, "错误的短信模板ID"));
		ERROR_MAP.put(205403, new TupleThree<>(true, true, "网络错误,请重试"));
		ERROR_MAP.put(205404, new TupleThree<>(false, false, null));
		ERROR_MAP.put(205405, new TupleThree<>(true, false, "号码异常/同一号码发送次数过于频繁"));
		ERROR_MAP.put(205406, new TupleThree<>(false, false, "不被支持的模板"));

		ERROR_MAP.put(10001, new TupleThree<>(false, false, "错误的请求KEY"));
		ERROR_MAP.put(10002, new TupleThree<>(false, false, "该KEY无请求权限"));
		ERROR_MAP.put(10003, new TupleThree<>(false, false, "KEY过期"));
		ERROR_MAP.put(10004, new TupleThree<>(false, false, "错误的OPENID"));
		ERROR_MAP.put(10005, new TupleThree<>(true, false, "应用未审核超时，请提交认证"));
		ERROR_MAP.put(10007, new TupleThree<>(false, false, "未知的请求源"));
		ERROR_MAP.put(10008, new TupleThree<>(true, false, "被禁止的IP"));
		ERROR_MAP.put(10009, new TupleThree<>(true, false, "被禁止的KEY"));
		ERROR_MAP.put(10011, new TupleThree<>(true, false, "当前IP请求超过限制"));
		ERROR_MAP.put(10012, new TupleThree<>(true, false, "请求超过次数限制"));
		ERROR_MAP.put(10013, new TupleThree<>(true, false, "测试KEY超过请求限制"));
		ERROR_MAP.put(10020, new TupleThree<>(true, false, "聚合接口维护"));
		ERROR_MAP.put(10021, new TupleThree<>(true, false, "接口停用"));
	}

	@Override
	public void send(PlatformTemplateValue platformTemplate, SmsEventData eventData) {
		String key = this.checkConfigInfo(platformTemplate, "key", String.class, true);
		String url = this.checkConfigInfo(platformTemplate, "url", String.class, true);
		Map<String, String> reqMap = platformTemplate.generatePlatformParameter(eventData.getParams());

		Map<String, Object> m = new HashMap<String, Object>(16);
		m.put("key", key);
		m.put("tpl_value", getMessageKV(reqMap));
		m.put("tpl_id", Integer.valueOf(platformTemplate.getTemplateCode()));
		m.put("mobile", eventData.getMobilePhone());

		String postParam = HttpUtil.postParam(m, url);
		JSONObject json = JSON.parseObject(postParam);
		Integer errorCode = json.getInteger("error_code");
		if (errorCode != null && errorCode != 0) {
			boolean isSupportRepeatSend = false;
			boolean isRepeatSend = false;
			Object reason = null;
			TupleThree<Boolean, Boolean, String> errorInfo = ERROR_MAP.get(errorCode);
			if (errorInfo != null) {
				isSupportRepeatSend = errorInfo.getItem1();
				isRepeatSend = errorInfo.getItem2();
				reason = errorInfo.getItem3();
			}
			if (reason == null) {
				reason = json.get("reason");
			}
			if (reason == null) {
				reason = "";
			}
			throw new SmsSendException(isSupportRepeatSend, isRepeatSend, errorCode + " : " + reason);
		}
	}

	/**
	 * @param m
	 *            平台模板实例中的参数，里面是短信模板中参数键值对
	 * @return 聚合平台短信模板提交参数的指定格式字符串
	 * @throws UnsupportedEncodingException
	 */
	private String getMessageKV(Map<String, String> m) {
		try {
			StringBuilder sb = new StringBuilder();
			int n = 0;
			for (Entry<String, String> e : m.entrySet()) {
				if (n > 0) {
					sb.append("&");
				}
				sb.append(e.getKey() + "=" + URLEncoder.encode(String.valueOf(e.getValue()), "UTF-8"));
				n = 1;
			}
			return URLEncoder.encode(sb.toString(), "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		return "";
	}
}
